import React, {
  createContext,
  ReactNode,
  useCallback,
  useState,
  useMemo,
  useContext,
  useEffect,
} from 'react';

import type { LoginUser, LoginUserStoreApi } from '@/types/store';

const LoginUserContext = createContext<LoginUserStoreApi>({
  loginUser: {},
  updateInfo: () => null,
  clearInfo: () => null,
});

const LOGIN_USER_KEY = 'LOGIN_USER';

export const LoginUserContextProvider = (props: { children?: ReactNode }) => {
  const { loginUser, updateLoginUserInfo, clearLoginUserInfo } = useLoginUserProvide();

  return (
    <LoginUserContext.Provider
      value={{
        loginUser,
        updateInfo: updateLoginUserInfo,
        clearInfo: clearLoginUserInfo,
      }}
    >
      {props.children}
    </LoginUserContext.Provider>
  )
}

function useLoginUserProvide() {
  const [loginUser, setLoginUser] = useState<Partial<LoginUser>>({});

  const updateLoginUserInfo = useCallback((info: Partial<LoginUser>) => {
    setLoginUser((prev) => ({ ...prev, ...info }));
  }, []);

  const clearLoginUserInfo = useCallback(() => {
    setLoginUser({});
  }, []);

  useEffect(() => {
    const user = localStorage.getItem(LOGIN_USER_KEY);
    if (user) {
      updateLoginUserInfo(JSON.parse(user));
    }
  }, []);

  useEffect(() => {
    localStorage.setItem(LOGIN_USER_KEY, JSON.stringify({ ...loginUser }));
  }, [loginUser]);

  return {
    loginUser,
    updateLoginUserInfo,
    clearLoginUserInfo,
  };
}

export function useLoginUser() {
  const ctx = useContext(LoginUserContext);

  return useMemo(() => {
    return ctx.loginUser || {};
  }, [ctx.loginUser]);
}

export function useUpdateLoginUser() {
  const ctx = useContext(LoginUserContext);

  return useMemo(() => {
    return ctx.updateInfo;
  }, [ctx.updateInfo]);
}
